package cn.lingyangwl.agile.food.model.entity;

import cn.lingyangwl.agile.model.BasePO;
import cn.lingyangwl.agile.tenant.core.DataIsolation;
import cn.lingyangwl.framework.tool.core.MD5Utils;
import cn.lingyangwl.framework.tool.core.exception.BizException;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 购物车
 *
 * @author shenguangyang
 */
@Getter
@Setter
@Slf4j
@TableName(value = "food_cart", autoResultMap = true)
@DataIsolation(filterTenant = true, filterUser = true, tableName = "food_cart")
public class Cart extends BasePO {
    @TableId
	private Long id;

	/**
	 * 购物车编号, md5(商品id + skuId + 规格id)
	 */
	private String cartNo;

	/**
	 * 是否为多规格商品
	 */
	private Boolean multiSpec;
	
	/**
	 * 会员id
	 */
	private Long userId;
	
	/**
	 * 商品id
	 */
	private Long goodsId;
	
	/**
	 * 商品数量
	 */
	private Integer goodsNum;
	
	/**
	 * 规格id
	 */
	private Long goodsSkuId;
	
	/**
	 * 属性
	 */
	@TableField(value = "attribute", typeHandler = AttributeTypeHandler.class)
	private List<Attribute> attributeList;
	
	/**
	 * 包装费
	 */
	private BigDecimal bagPrice;

	/**
	 * 总价
	 * @deprecated
	 */
	private BigDecimal price;
	
	/**
	 * 商品价格
	 */
	private BigDecimal goodsPrice;
	
	/**
	 * 商品综合描述
	 */
	@TableField(value = "`describe`")
	private String describe;
	
	/**
	 * 购物车类型: 0外卖, 1店内
	 */
	private Integer cartType;

	/**
	 * 桌号id
	 */
	private Long tableId;

	/**
	 * 创建时间
	 */
	@TableField(fill = FieldFill.INSERT)
	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
	@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
	private Date createdAt;

	/**
	 * 更新时间
	 */
	@TableField(fill = FieldFill.INSERT_UPDATE)
	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
	@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
	private Date updatedAt;

    public static LambdaQueryWrapper<Cart> lqw() {
		return Wrappers.lambdaQuery();
	}

	public static LambdaUpdateWrapper<Cart> luw() {
		return Wrappers.lambdaUpdate();
	}

	public static class AttributeTypeHandler extends AbstractJsonTypeHandler<List<Attribute>> {

		@Override
		protected List<Attribute> parse(String json) {
			return JSON.parseArray(json, Attribute.class);
		}

		@Override
		protected String toJson(List<Attribute> obj) {
			String str = JSON.toJSONString(obj);
			if (str.length() > 1024) {
				throw new BizException("属性太大, 请联系管理员");
			}
			return str;
		}
	}

	/**
	 * 商品属性, 查询时候要校验商品属性是否已被商家更改
	 */
	@Data
	public static class Attribute {
		private Long id;

		private String name;

		private List<GoodsAttribute.Values> values;

		public List<String> flatKeys() {
			return values.stream().map(e -> id + "_" + e.getName()).collect(Collectors.toList());
		}
	}

	public void genCartNo() {
		List<Attribute> attributes = Optional.ofNullable(this.attributeList).orElse(Collections.emptyList());
		String attrStr = attributes.stream()
			.map(e -> e.getId() + e.getValues().stream().map(GoodsAttribute.Values::getName).sorted().collect(Collectors.joining()))
			.sorted().collect(Collectors.joining());
		try {
			this.cartNo = MD5Utils.md5(this.goodsId + this.goodsSkuId + attrStr);
		} catch (Exception e) {
			log.error("error: ", e);
			throw new BizException("生成购物车编号失败");
		}
	}
}
